Go 的 exec 包-执行命令
执行命令并获得输出结果
func main() {
cmd := exec.Command("ls", "-lah")
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("cmd.Run() failed with %s\n", err)
}
fmt.Printf("combined out:\n%s\n", string(out))
}
将 stdout 和 stderr 分别处理
func main() {
cmd := exec.Command("ls", "-lah")
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
log.Fatalf("cmd.Run() failed with %s\n", err)
}
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
fmt.Printf("out:\n%s\nerr:\n%s\n", outStr, errStr)
}
配置环境变量
改变执行程序的环境(environment)
cmd := exec.Command("programToExecute")
additionalEnv := "FOO=bar"
newEnv := append(os.Environ(), additionalEnv)
cmd.Env = newEnv
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("cmd.Run() failed with %s\n", err)
}
fmt.Printf("%s", out)
预先检查程序是否存在
可以调用 exec.LookPath
方法来检查:
func checkLsExists() {
path, err := exec.LookPath("ls")
if err != nil {
fmt.Printf("didn't find 'ls' executable\n")
} else {
fmt.Printf("'ls' executable is in '%s'\n", path)
}
}
或者直接使用 os.Stat("appName")
检查开了几个子进程
利用进程名获取进程号(以自己创建的进程 middlebaby 为例)
ps -ef|grep middlebaby|grep -v "grep"|awk '{print $2}'
grep 的输出都会有 grep 自身这个进程在,用 grep -v "grep"
可以把这一行干掉,然后 awk '{print $2}'
就是打印第二列数字,即 16154 (这里因为是通过 makefile 启动的,所以有两个进程)
awk 是处理文本文件的一个应用程序,几乎所有 Linux 系统都自带这个程序。它依次处理文件的每一行,并读取里面的每一个字段。对于日志、CSV 那样的每行格式相同的文本文件,awk 可能是最方便的工具。
使用 pgrep 命令检查子进程
pgrep -P $parent_pid
pgrep 允许你基于给定条件来查找正在运行的程序的进程 ID。它可以是进程名字的全称或者一部分,进程运行者,或者其他属性。
或者使用 ps 的 ppid flag
ps --ppid $parent_pid